iT邦幫忙

2026 iThome 鐵人賽

DAY 8
0
Build on Google AI

用 Google AI 打造「因材施教」的個人化 AI 虛擬助教系列 第 8 篇

Day 08 |【Context 管理】如何讓 AI 助教記住學生的學習歷程與歷史對話?

  • 分享至 

  • xImage
  •  

【今日開發目標】

今天主要處理的是 **Context(上下文)**讓它不只是「問一題、回答一題」。

簡單來說,就是讓 AI 記得學生前面講過什麼。這樣學生下一句就算沒有把前面的關鍵字再講一次,AI 也可以根據前面的對話接著回答。

【Google AI 工具實作過程】

這次主要是在 Node.js 後端處理對話歷史。

原本每次呼叫 API 時,AI 只會看到「這一次」的問題。如果學生第一輪問:

我想學 Python 的 list 觀念。

第二輪只問:

那如果資料不能被修改,我該選哪一個?

如果沒有把前面的對話一起傳進去,AI 其實不知道「哪一個」是在問什麼。

因此這次我把歷史對話一起整理成 Gemini API 可以使用的 contents 格式。

1. 建立 JSON 歷史紀錄

每一輪對話都會記錄使用者和 AI 的內容,例如:

{
  role: 'user',
  parts: [{ text: '我想學 Python 的 list 觀念。' }]
}

AI 回覆則會記成:

{
  role: 'model',
  parts: [{ text: '...' }]
}

這樣每次有新的問題,就可以把前面的對話一起送給模型。

2. 在後端先清洗歷史資料

在 server.js 裡,我先對前端傳過來的 history 做一次整理。

主要使用 .filter() 和 .map(),把沒有 role、parts 或格式不正確的資料先排除掉,再統一成 Gemini API 可以接受的格式。

這一步看起來可能有點多餘,但如果之後前端傳進來的資料有缺漏,至少不會因為一筆格式錯誤的資料,整個 API 就直接掛掉。

3. 把歷史紀錄和新問題組合起來

整理完之後,再利用 Spread Operator:

const contents = [
  ...formattedHistory,
  {
    role: 'user',
    parts: [{ text: message }],
  },
];

把過去的對話和這次的新問題放在同一個 contents 裡。

這樣 Gemini 收到的就不只是最新一句,而是可以看到前面的對話脈絡。

【實際測試】

為了確認 Context 真的有作用,我在 test-chat.js 裡設計了兩輪測試。

第一輪先問:

我想學 Python 的 list 觀念。

AI 回答之後,把這一輪的 user 和 model 對話存進 history。

接著第二輪故意不再提 list,只問:

那如果資料「不能被修改」,我該選哪一個?

這裡就是這次測試的重點。

如果 AI 有成功讀取前面的 Context,它就應該知道現在還是在討論 Python 的資料結構,進一步帶到 tuple。

這種測試比單純看「AI 有沒有回答成功」更能確認上下文功能到底有沒有真的串起來。

【遇到的問題】

Cannot use import statement outside a module

這次實作中間也遇到一個 Node.js 很常見的錯誤:

SyntaxError: Cannot use import statement outside a module

一開始看到這個錯誤會有點莫名其妙,明明 import 的寫法本身沒有問題,為什麼 Node.js 不認?

後來才發現是因為我在 server.js 使用的是 ES Module 的寫法:

import express from 'express';

但 Node.js 預設不一定會把 .js 當成 ES Module 處理。

所以最後直接在 package.json 加上:

{
  "type": "module"
}

告訴 Node.js:

這個專案的 JavaScript 使用 ES Module。

加完之後,import 語法就可以正常執行了。

這次也算是再次感受到,實際串 API 的時候,不是只有「程式碼寫對就好」,專案本身的環境設定也會影響程式能不能跑。

【這次做完學到什麼】

這次最大的差別其實不是多了一個 history 變數,而是開始比較能理解 AI 對話記憶到底是怎麼實作的。AI 並不是自己突然「記住」前面講過的東西,而是我們在每次送出新的問題時,把之前的對話整理好,再一起傳給模型,這樣下一次提問時,就可以繼續把前面的內容帶進去。

對 AI 助教來說,這個功能也滿重要的。

因為學生實際問問題時,不太可能每一句都講得很完整。

可能上一句還在問:

list 跟 tuple 有什麼差?

下一句就直接變成:

那不能修改的是哪個?

如果每次都要重新把完整問題講一次,其實滿累的。

有 Context 之後,學生就可以用比較接近平常講話的方式一直追問,AI 再根據前面的內容接著引導。

【未來教育反思】

做到這裡,我覺得 Context 對 AI 助教來說,比單純「回答得很準」還重要。

因為實際學習的過程本來就是連續的。學生可能先搞不懂一個觀念,問了一次之後還是不確定,接著換個方式問;或者只丟一句「那如果不能改呢?」。如果 AI 每次都把它當成全新的問題,學生就會一直重複前面的內容。但如果 AI 能保留對話脈絡,就可以比較接近真正的「一來一往」。

這也讓前面做的蘇格拉底式教學規則開始比較有意義。因為 AI 不只是一直問學生問題,而是可以根據學生前面說過的內容,決定下一步要怎麼引導。

當然,目前這個版本還只是把對話歷史完整帶進去,之後還可以再思考要不要加入更進一步的學生狀態,例如「目前學到哪裡」、「哪個觀念容易搞錯」等等。

【明日預告】

今天先把 AI 的 Context 和對話記憶處理好。

明天 Day 09 就要把前幾天做好的東西真正接在一起,進入【前後端串接】。

也就是把今天的 Node.js 後端 API,正式接到之前用 Google Stitch 做好的前端介面。

希望明天做完之後,就不只是從終端機測試,而是可以直接在網頁上跟自己的 AI 助教對話。


上一篇
Day 07|【API 串接】用 Python 呼叫 Google GenAI SDK:從第一個 API 回應開始理解專案架構
下一篇
Day 09|【前後端串接】將 Python API 與 Stitch 前端介面串接實戰與除錯血淚史
系列文
用 Google AI 打造「因材施教」的個人化 AI 虛擬助教 共 28 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言